package com.example.smsquiz;

import java.io.File;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;

public class SmsQuizService extends Service {

    public final static String PHONE_NUMBER_KEY = "phoneNumber";
    public final static String START_PHONE_NUMBER_KEY = "startPhoneNumber";
    public final static String START_WORD_KEY = "startWord";
    public final static String ANSWER_TIME_FROM_KEY = "answerTimeFrom";
    public final static String ANSWER_TIME_TO_KEY = "answerTimeTo";
    public final static String TARGET_KEY = "target";

    private ExecutorService executor;
    private static SmsRun smsRun;

    public static Boolean isActive(){
        return smsRun != null && smsRun.Active();
    }

    public void onCreate() {
        super.onCreate();
        executor = Executors.newFixedThreadPool(1);
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        File external = Environment.getExternalStorageDirectory();
        File db = new File(external, "normal.txt");
        if (!db.exists()) {
            File sd = new File(external, "external_sd");
            db = new File(sd, "normal.txt");
        }
        if (db.exists()) {
            AppModel.getInstance().initialize(db.getAbsolutePath());
            String phoneNumber = intent.getStringExtra(PHONE_NUMBER_KEY);
            String startPhoneNumber = intent.getStringExtra(START_PHONE_NUMBER_KEY);
            String startWord = intent.getStringExtra(START_WORD_KEY);
            int target = intent.getIntExtra(TARGET_KEY, 0);
            int intervalFromSec = intent.getIntExtra(ANSWER_TIME_FROM_KEY, 0);
            int intervalToSec = intent.getIntExtra(ANSWER_TIME_TO_KEY, 0);
            if (phoneNumber != null
                    && phoneNumber.length() > 0
                    && startPhoneNumber != null
                    && startPhoneNumber.length() > 0) {
                AppModel.getInstance().sendSms(startPhoneNumber, startWord);
                InitialParamsDTO params = new InitialParamsDTO(phoneNumber, target, intervalFromSec, intervalToSec);
                smsRun = new SmsRun(params);
                executor.execute(smsRun);
            }
        } else {
            AppLogger.Write("Database not found");
        }
        return super.onStartCommand(intent, flags, startId);
    }

    public void onDestroy() {
        smsRun.stop();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    class SmsRun implements Runnable {

        private InitialParamsDTO parameters;
        private Boolean isActive;
        private int answerCounter;

        public SmsRun(InitialParamsDTO params) {
            parameters = params;
        }

        public Boolean Active(){
            return isActive;
        }

        @Override
        public void run() {
            try {
                isActive = true;
                answerCounter = 0;
                Random rand = new Random();
                AppLogger.Write("Service started");
                while (isActive && answerCounter < parameters.getTarget()) {
                    analyzeIncomingMessages(rand);
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        AppLogger.WriteError(e);
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                AppLogger.WriteError(e);
            }
        }

        private void analyzeIncomingMessages(Random rand){
            SmsDTO message;
            while ((message = AppModel.getInstance().getMessage()) != null) {
                AppLogger.Write("SMS in service");
                if (message.getPhoneNumber().equals(parameters.getPhoneNumber())) {
                    String question = message.getMessageBody();
                    double randVal = rand.nextDouble();
                    int waitFrom = parameters.getAnswerIntervalFromSec();
                    int waitTo = parameters.getAnswerIntervalToSec();
                    int wait = (int) (waitFrom + (waitTo - waitFrom) * randVal);
                    processQuestion(wait, question);
                }
            }
        }

        private void processQuestion(int wait, String question) {
            String answer = AppModel.getInstance().getAnswerOnSimilarQuestion(question);
            if (answer == null) {
                AppLogger.Write("No answer");
                AppModel.getInstance().setQuestionProcessing(true);
                Context context = getApplicationContext();
                Intent setAnswerIntent = new Intent(context, SetAnswerActivity.class);
                setAnswerIntent.putExtra(SetAnswerActivity.QUESTION_KEY, question);
                String title = "No answer";
                String message = "You need set answer to continue";

                Notification notification = new Notification(R.drawable.ic_launcher, title, System.currentTimeMillis()); //генерируем уведомление
                notification.flags |= Notification.FLAG_AUTO_CANCEL;
                PendingIntent contentIntent = PendingIntent.getActivity(context, 0, setAnswerIntent, PendingIntent.FLAG_CANCEL_CURRENT);
                notification.setLatestEventInfo(context, title, message, contentIntent);
                NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                manager.notify(0, notification); // отображаем его пользователю.

                while (AppModel.getInstance().getQuestionProcessing()){
                    // wait adding
                }
                answer = AppModel.getInstance().getAnswerOnSimilarQuestion(question);
                if (answer == null) {
                    return;
                }
            }

            if (wait > 0)
                try {
                    TimeUnit.SECONDS.sleep(wait);
                } catch (InterruptedException e) {
                    AppLogger.WriteError(e);
                }

            int answerIndex = question.indexOf("=" + answer) - 1;
            if (answerIndex > 0) {
                String answerMessage = question.substring(answerIndex, answerIndex + 1);
                AppLogger.Write("Service send answer SMS");
                AppModel.getInstance().sendSms(parameters.getPhoneNumber(), answerMessage);
                answerCounter++;
            }
        }

        public void stop() {
            isActive = false;
        }

    }
}
